home *** CD-ROM | disk | FTP | other *** search
- /*
- linfit(XYpoints)
- Fit data to a straight line using linear regression formula.
- */
-
- /* This file implements linfit() as a native powerPC code fragment.
- For comparison see:
- linfit68K.c -- 68K code seg without A4 globals
- linfit68Kg.c -- 68K code seg with A4 globals
- */
-
- #include "callbackg.h"
- #include <fp.h> // needed for sqrt()
-
- #include <CodeFragments.h>
- /* Fragment initialization entry point. Must match symbol name in linker prefs */
- OSErr InitCFun(CFragInitBlockPtr iblk);
-
- static short linfit(double *retval)
- {
- EXPR arr;
- double x,y,*iptr,*jptr,intercept;
- double sumx,sumxx,sumy,sumyy,sumxy,Sxx,Sxy;
- short isarray;
- long n,count;
-
- sumx=0; sumxx=0; sumy=0; sumyy=0; sumxy=0;
- n = 0;
- MakeParmExpr(0,&arr);
- ProbeExpr(arr,&x,&isarray,&count);
- if(!isarray || count<2)
- {
- ErrMsg(" linfit() expects array of {x,y}",0L);
- FreeExpr(arr);
- return(FALSE);
- }
- AddIndex(&arr,&iptr); // arr[i] is {x,y}
- AddIndex(&arr,&jptr); // j picks x or y
- while(count--)
- {
- *jptr = 1;
- if(EvalExpr(arr,&x) && x==x)
- {
- *jptr = 2;
- if(EvalExpr(arr,&y) && y==y)
- {
- sumx += x;
- sumxx += x*x;
- sumy += y;
- sumyy += y*y;
- sumxy += x*y;
- n++;
- }
- }
- *iptr += 1;
- }
- Sxx=n*sumxx-sumx*sumx;
- Sxy=n*sumxy-sumx*sumy;
-
- SetVarVal("slope",Sxy/Sxx);
- intercept=(sumxx*sumy-sumx*sumxy)/(n*sumxx-sumx*sumx);
- SetVarVal("intercept",intercept);
- *retval = Sxy/sqrt(Sxx*(n*sumyy-sumy*sumy)); // return correlation coeff
-
- FreeExpr(arr);
- return(TRUE);
- }
-
-
-
- OSErr InitCFun(CFragInitBlockPtr iblk)
- {
- AddCFun("linfit","XYpoints",&linfit,NULL);
- return noErr;
- }
-
-